﻿using System;
using System.Collections.Generic;

using ZKLibrarys.Constant;
using ZKLibrarys.Models;

namespace ZKLibrarys.zkem
{
    /// <summary>
    /// 中控考勤原版API简化
    /// </summary>
    public static class ZKAPIOriginal
    {
        #region 5.2.1 考勤记录数据---------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 5.2.1.2
        /// 读取考勤记录到PC的内部缓冲区，同ReadGeneralLogData
        /// </summary>
        /// <returns></returns>
        public static bool ReadAllGLogData(int ID)
        {
            return ZKGConf.GetZKClass(ID).ReadAllGLogData(ID);
        }

        /// <summary>
        /// 5.2.1.10
        /// 清空指定考勤机的所有考勤记录
        /// </summary>
        /// <returns></returns>
        public static bool ClearGLog(int ID)
        {
            return ZKGConf.GetZKClass(ID).ClearGLog(ID);
        }

        #endregion

        #region 5.2.3用户信息相关---------------------------------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 5.2.3.1
        /// 读取所有的用户信息到PC内存中，包括用户编号，密码，姓名，卡号等，指纹模板除外。
        /// 在该函数执行完成后，可调用函数GetAllUserID取出用户信息
        /// </summary>
        /// <param name="ID">考勤机ID</param>
        /// <returns></returns>
        public static bool ReadAllUserID(int ID)
        {
            return ZKGConf.GetZKClass(ID).ReadAllUserID(ID);
        }

        /// <summary>
        /// 5.2.3.3 适用于TFT,IFACE设备
        /// 设置用户是否可用
        /// </summary>
        /// <param name="EnrollID">员工号</param>
        /// <param name="Flag">用户启用标志</param>
        /// <returns></returns>
        [Obsolete("新机构已经不支持该功能")]
        public static bool SSR_EnableUser(int ID, string EnrollID, bool Flag)
        {
            return ZKGConf.GetZKClass(ID).SSR_EnableUser(ID, EnrollID, Flag);
        }

        /// <summary>
        /// 5.2.3.9 适用于TFT,IFACE设备
        /// 取得所有用户信息。在该函数执行之前，可用 ReadAllUserID 读取到所有用户信息到内存，SSR_GetAllUserInfo每执行一次，
        /// 指向用户信息指针移到下一记录，当读完所有用户信息后，函数返回False。
        /// </summary>
        /// <returns></returns>
        public static List<ModelUserInfo> SSR_GetAllUserInfo(int ID)
        {
            List<ModelUserInfo> userInfos = new List<ModelUserInfo>();
            int V = 0, M;
            M = GetDeviceStatus(ID, StatusCode.UserCount);
            OnSSR_GetAllUserInfoValueChange?.Invoke(V, M);
            while (ZKGConf.GetZKClass(ID).SSR_GetAllUserInfo(ID, out string EnrollID, out string Name, out string Password, out int Privilege, out bool Enabled))
            {
                userInfos.Add(new ModelUserInfo
                {
                    ID = ID,
                    EnrollID = EnrollID,
                    Name = Name,
                    Password = Password,
                    Privilege = (MachinePrivilege)Privilege,
                    Enabled = Enabled
                });
                OnSSR_GetAllUserInfoValueChange(V++, M);
            }
            return userInfos;

        }
        public delegate void SSR_GetAllUserInfoEventHandle(int Value, int Max);
        /// <summary>
        /// 取得所有用户信息时的进度数据改变事件
        /// </summary>
        public static event SSR_GetAllUserInfoEventHandle OnSSR_GetAllUserInfoValueChange;


        /// <summary>
        /// 5.2.3.15 适用于TFT,IFACE设备
        /// 1.旧架构：0为普通用户，1为登记员，2为管理员，3为超级管理员。
        /// 新架构：0为普通用户，1，2,4为自定义用户角色，3超级管理员。
        /// 2.Enable参数代表用户是否启用，1为启用，0为禁用。
        /// </summary>
        /// <param name="EnrollID">员工号</param>
        /// <param name="Name">输出姓名</param>
        /// <param name="Password">输出密码</param>
        /// <param name="Privilege">输出权限</param>
        /// <param name="Enable">输出是否启用</param>
        /// <returns></returns>
        public static bool SSR_GetUserInfo(int ID, string EnrollID, out string Name, out string Password, out int Privilege, out bool Enable)
        {
            return ZKGConf.GetZKClass(ID).SSR_GetUserInfo(ID, EnrollID, out Name, out Password, out Privilege, out Enable);
        }

        /// <summary>
        /// 5.2.3.17 适用于TFT,IFACE设备
        /// 设置指定用户的用户信息，若机器内没用该用户，则会创建该用户
        /// 旧架构：0为普通用户，1为登记员，2为管理员，3为超级管理员。
        /// 新架构：0为普通用户，1，2,4为自定义用户角色，3超级管理员。
        /// 2.Enable参数代表用户是否启用，1为启用，0为禁用。 
        /// </summary>
        /// <param name="EnrollID">员工号</param>
        /// <param name="Name">员工姓名</param>
        /// <param name="Password">密码</param>
        /// <param name="Privilege">权限</param>
        /// <param name="Enable">是否启用</param>
        /// <returns></returns>
        public static bool SSR_SetUserInfo(int ID, string EnrollID, string Name, string Password, int Privilege, bool Enable)
        {
            return ZKGConf.GetZKClass(ID).SSR_SetUserInfo(ID, EnrollID, Name, Password, Privilege, Enable);
        }

        #endregion

        #region 5.2.4登记数据（同时包括用户信息和指纹）------------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 5.2.4.4
        /// 删除登记数据
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="backupID">
        /// 指纹索引
        /// 为0-9，同时会查询该用户是否还有其他指纹和密码，如都没有，则删除该用户。
        /// 为10,是代表删除的是密码，同时会查询该用户是否有指纹数据，如没有，则删除该用户。
        /// 为11,是代表删除该用户所有指纹数据，
        /// 为12,代表删除该用户（包括所有指纹和卡号、密码数据）。
        /// </param>
        /// <returns></returns>
        public static bool SSR_DeleteEnrollData(int ID, string EnrollID, int BackupID)
        {
            return ZKGConf.GetZKClass(ID).SSR_DeleteEnrollData(ID, EnrollID, BackupID);
        }

        /// <summary>
        /// 5.2.4.5 
        /// 删除登记数据
        /// </summary>
        /// <param name="ID">考勤机号</param>
        /// <param name="EnrollID">用户号</param>
        /// <param name="BackupID">
        /// 指纹索引
        /// 0-9，同时会查询该用户是否还有其他指纹和密码，如都没有，则删除该用户。
        /// 10是代表删除的是密码，同时会查询该用户是否有指纹数据，如没有，则删除该用户。
        /// 11和13是代表删除该用户所有指纹数据。
        /// 12代表删除该用户（包括所有指纹和卡号、密码数据）。
        /// 和SSR_DeleteEnrollData不同的是删除所有指纹数据可用参数13实现，该函数具有更高效率。
        /// </param>
        /// <returns></returns>
        public static bool SSR_DeleteEnrollDataExt(int ID, string EnrollID, int BackupID)
        {
            return ZKGConf.GetZKClass(ID).SSR_DeleteEnrollDataExt(ID, EnrollID, BackupID);
        }
        #endregion

        #region 5.2.5指纹模板相关---------------------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 5.2.5.1
        /// 读取机器内所有指纹模板到PC内存，该函数一次性将所有指纹数据读到内存，相比于一个一个从机器获取，该函数具有更高效率
        /// </summary>
        /// <returns></returns>
        public static bool ReadAllTemplate(int ID)
        {
            return ZKGConf.GetZKClass(ID).ReadAllTemplate(ID);
        }

        /// <summary>
        /// 5.2.5.2
        /// 以二进制方式获取用户指纹模板,和SSR_GetUserTmpStr不同的仅是指纹模板格式不同而已
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="FingerIndex">指纹号</param>
        /// <param name="TmpData">输出指纹数据</param>
        /// <param name="TmpLength">输出指纹数据长度</param>
        /// <returns></returns>
        [Obsolete("这个API输出的指纹数据是byte,但是实际上应该是byte[],所以API执行出未知错误", true)]
        public static bool SSR_GetUserTmp(int ID, string EnrollID, int FingerIndex, out byte TmpData, out int TmpLength)
        {
            return ZKGConf.GetZKClass(ID).SSR_GetUserTmp(ID, EnrollID, FingerIndex, out TmpData, out TmpLength);
        }

        /// <summary>
        /// 5.2.5.3
        /// 以字符串方式获取用户指纹模板，和SSR_GetUserTmp不同的仅是指纹模板格式不同而已
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="FingerIndex">指纹号</param>
        /// <param name="TmpData">输出指纹数据</param>
        /// <param name="TmpLength">输出指纹数据长度</param>
        /// <returns></returns>
        public static bool SSR_GetUserTmpStr(int ID, string EnrollID, int FingerIndex, out string TmpData, out int TmpLength)
        {
            return ZKGConf.GetZKClass(ID).SSR_GetUserTmpStr(ID, EnrollID, FingerIndex, out TmpData, out TmpLength);
        }

        /// <summary>
        /// 5.2.5.4
        /// 以二进制方式上传用户指纹模板，和SSR_SetUserTmpStr不同的仅是指纹模板格式不同而已
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="FingerIndex">指纹号</param>
        /// <param name="TmpData">指纹数据</param>
        /// <returns></returns>
        [Obsolete("这个API输出的指纹数据是byte,但是实际上应该是byte[],所以API执行出未知错误", true)]
        public static bool SSR_SetUserTmp(int ID, string EnrollID, int FingerIndex, ref byte TmpData)
        {
            return ZKGConf.GetZKClass(ID).SSR_SetUserTmp(ID, EnrollID, FingerIndex, ref TmpData);
        }

        /// <summary>
        /// 5.2.5.5
        /// 以字符串方式上传用户指纹模板，和SSR_SetUserTmp不同的仅是指纹模板格式不同而已
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="FingerIndex">指纹号</param>
        /// <param name="TmpData">指纹数据</param>
        /// <returns></returns>
        public static bool SSR_SetUserTmpStr(int ID, string EnrollID, int FingerIndex, string TmpData)
        {
            return ZKGConf.GetZKClass(ID).SSR_SetUserTmpStr(ID, EnrollID, FingerIndex, TmpData);
        }

        /// <summary>
        /// 5.2.5.7
        /// 删除指定的用户指纹模板
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="FingerIndex">指纹号</param>
        /// <returns></returns>
        public static bool SSR_DelUserTmp(int ID, string EnrollID, int FingerIndex)
        {
            return ZKGConf.GetZKClass(ID).SSR_DelUserTmp(ID, EnrollID, FingerIndex);
        }

        /// <summary>
        /// 5.2.5.12
        /// 以二进制方式上传用户ZKFinger 10.0指纹模板 ，和SetUserTmpExStr不同的仅是指纹模板格式不同而已
        /// 1.机器上必须已存在该用户或者将用户信息同时上传，相同用户的相同索引号模板如果已经登记，则覆盖。
        /// 要求机器固件支持胁迫指纹功能（固件内部版本号 Ver6.60 及以上）。
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="FingerIndex">指纹号</param>
        /// <param name="Flag">标示指纹模板是否有效或者是否为胁迫指纹
        /// Flag参数标示指纹模板是否有效或者是否为胁迫指纹，其具体表示为：0 表示指纹模板无效，1 表示指纹模板有效，3 表示胁迫指纹。
        /// </param>
        /// <param name="TmpData">二进制指纹数据指针</param>
        /// <returns></returns>
        [Obsolete("这个API输出的指纹数据是byte,但是实际上应该是byte[],所以API执行出未知错误", true)]
        public static bool SetUserTmpEx(int ID, string EnrollID, int FingerIndex, int Flag, ref byte TmpData)
        {
            return ZKGConf.GetZKClass(ID).SetUserTmpEx(ID, EnrollID, FingerIndex, Flag, ref TmpData);
        }

        /// <summary>
        /// 5.2.5.13
        /// 以字符串方式上传用户ZKFinger 10.0指纹模板 ，和SetUserTmpEx不同的仅是指纹模板格式不同而已
        /// 1.机器上必须已存在该用户或者将用户信息同时上传，相同用户的相同索引号模板如果已经登记，则覆盖。
        /// 要求机器固件支持胁迫指纹功能（固件内部版本号 Ver6.60 及以上）。
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="FingerIndex">指纹号</param>
        /// <param name="Flag">标示指纹模板是否有效或者是否为胁迫指纹
        /// Flag参数标示指纹模板是否有效或者是否为胁迫指纹，其具体表示为：0 表示指纹模板无效，1 表示指纹模板有效，3 表示胁迫指纹。
        /// </param>
        /// <param name="TmpData">指纹数据</param>
        /// <returns></returns>
        public static bool SetUserTmpExStr(int ID, string EnrollID, int FingerIndex, int Flag, string TmpData)
        {
            return ZKGConf.GetZKClass(ID).SetUserTmpExStr(ID, EnrollID, FingerIndex, Flag, TmpData);
        }

        /// <summary>
        /// 5.2.5.17
        /// 以字符串方式获得用户ZKFinger 10.0指纹模板 ,和GetUserTmpEx不同的仅是指纹模板格式不同而已。
        /// 1.要求机器固件支持胁迫指纹功能（固件内部版本号 Ver6.60 及以上）。
        /// 2.Flag参数标示指纹模板是否有效或者是否为胁迫指纹，其具体表示为：0 表示指纹模板无效，1 表示指纹模板有效，3 表示胁迫指纹。 
        /// </summary>
        /// <param name="EnrollID">用户号</param>
        /// <param name="FingerIndex">指纹号</param>
        /// <param name="Flag">标示指纹模板是否有效或者是否为胁迫指</param>
        /// <param name="TmpData">输出指纹数据</param>
        /// <param name="TmpLength">输出指纹数据长度</param>
        /// <returns></returns>
        public static bool GetUserTmpExStr(int ID, string EnrollID, int FingerIndex, out int Flag, out string TmpData, out int TmpLength)
        {
            return ZKGConf.GetZKClass(ID).GetUserTmpExStr(ID, EnrollID, FingerIndex, out Flag, out TmpData, out TmpLength);
        }
        #endregion

        #region 5.2.13系统数据管理相关--------------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 5.2.13.1
        /// 清楚机器内所有的数据
        /// </summary>
        /// <param name="ID">机器号</param>
        /// <returns>True,False</returns>
        public static bool ClearKeeperData(int ID)
        {
            return ZKGConf.GetZKClass(ID).ClearKeeperData(ID);
        }

        /// <summary>
        /// 5.2.13.2
        /// 清除机器内由DataFlag指定的记录
        /// </summary>
        /// <param name="DataFlag">
        /// 数据类型标志
        /// 1 考勤记录,2 指纹模板数据,3 无,4 操作记录,5 用户信息
        /// 当该参数为 5 时，即删除机器内所有用户，注：此操作同时会删除机器内所有指纹模板。
        /// </param>
        /// <returns>True,False</returns>
        public static bool ClearData(int ID, int DataFlag)
        {
            return ZKGConf.GetZKClass(ID).ClearData(ID, DataFlag);
        }

        /// <summary>
        /// 刷新机器内数据，一般在上传用户信息或指纹后调用，这样能使所作的修改立即起作用，起到同步作用
        /// </summary>
        /// <returns>True,False</returns>
        public static bool RefreshData(int ID)
        {
            return ZKGConf.GetZKClass(ID).RefreshData(ID);
        }
        #endregion

        #region 5.4机器管理-----------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 5.4.1
        /// 判断当前机器是否为彩屏机
        /// </summary>
        /// <returns></returns>
        public static bool IsTFTMachine(int ID)
        {
            return ZKGConf.GetZKClass(ID).IsTFTMachine(ID);
        }

        /// <summary>
        /// 5.4.2
        /// 获取机器内数据存储状态，例如管理员数，当前用户数等 
        /// </summary>
        /// <param name="status">
        /// 要获取的状态的状态码[StatusCode值]
        /// dwStatus参数为需获取的数据，范围为1-22，含义如下：
        /// 1 管理员数量
        /// 2 注册用户数量
        /// 3 机器内指纹模板数量
        /// 4 密码数量
        /// 5 操作记录数
        /// 6 考勤记录数
        /// 7 指纹模板容量
        /// 8 用户容量
        /// 9 考勤记录容量
        /// 10 剩余指纹模板容量
        /// 11 剩余用户数容量
        /// 12 剩余考勤记录容量
        /// 21 人脸总数
        /// 22 人脸容量
        /// </param>
        /// <returns>其他状况返回 0,函数执行失败返回 -9999</returns>
        public static int GetDeviceStatus(int ID, int Status)
        {
            int RValue = 0;
            if (ZKGConf.GetZKClass(ID).GetDeviceStatus(ID, Status, ref RValue))
            {
                return RValue;
            }
            else
            {
                return -9999;
            }
        }

        /// <summary>
        /// 5.4.3
        /// 获取机器相关信息，例如语言，波特率等
        /// </summary>
        /// <param name="Info">
        /// 需获取的信息类型
        /// Info参数表示需获取的信息类型，范围为1-68，不能等于65），具体含义如下：
        /// 1.最大管理员数，总是返回500
        /// 2.机器号
        /// 3.语言。在该情况下dwValue接收的返回值含义为：为0时语言后缀为’E’，一般代表英文；为1时其他状况；为2时语言后缀为’T’，一般代表繁体中文；为3时语言后缀为’L’，一般代表泰语。
        /// 4.空闲时长(分钟)，即空闲该段时间后机器进入待机或关机。
        /// 5.锁控时长，即锁驱动时长。
        /// 6.考勤记录报警数，即当考勤记录达到该数量时，机器会报警以提示用户。
        /// 7.操作记录报警数，即当操作记录达到该数量时，机器会报警以提示用户。
        /// 8.重复记录时间，即同一用户打同一考勤状态的最小时间间隔。
        /// 9.232/485通讯的波特率。在该情况下，dwValue接受的返回值含义为:0 1200bps;1 2400bps;2 4800bps;3 9600bps;4 19200bps；5 38400bps；6 57600bps；其他 115200bps。
        /// 10.奇偶校验，总是返回0。
        /// 11.停止位，总是返回0。
        /// 12.日期分隔符，总是返回1。
        /// 13.网络功能是否启用，返回值：1为启用，0为禁用。
        /// 14.RS232是否启用。
        /// 15.RS485是否启用。
        /// 16.是否有声音功能。
        /// 17.是否进行高速比对。
        /// 18.空闲方式，即空间时间后进入的状态，返回值：87为关机，88休眠。
        /// 19.自动关机时间点，默认值为255，即不自动关机。
        /// 20.自动开机时间点，默认值为 55，即不自动开机。
        /// 21.自动休眠时间点，默认值为255，即不自动休眠。
        /// 22.自动响铃时间点1，默认值为65535，即不自动响铃。
        /// 23.1:N比对匹配阀值。
        /// 24.登记时匹配阀值。
        /// 25.1:1匹配阀值。
        /// 26.验证时是否显示匹配分数。
        /// 27.同时开锁人数。
        /// 28.只验证号码卡。
        /// 29.网络速度。在该情况下，dwValue 接受的返回值含义为:1 100M-H；4 10M-F；5 100M-F；8 AUTO；其他 10M-H；。
        /// 30.卡是否必需注册。
        /// 31.机器在临时状态无操作自动返回的等待时间。
        /// 32.机器在输入PIN 号时无操作时自动返回的等待时间。
        /// 33.机器在进入菜单后无操作自动返回的等待时间。
        /// 34.时间格式。
        /// 35.是否必需使用1:1 比对。
        /// 36—40.自动响铃时间点2、3、4、5、6 ，默认值都为65535，即不自动响铃。
        /// 41—56.自动状态转换时间点1—16，默认值都为－1，即不会自动状态转换。
        /// 57.wiegand失败ID。
        /// 58.wiegand胁迫ID。
        /// 59.wiegand区位码。
        /// 60.wiegand输出的脉冲宽度。
        /// 61.wiegand输出的的脉冲间隔。
        /// 62.MIFARE卡存储指纹开始扇区数。
        /// 63.MIFARE卡存储指纹扇区总数。
        /// 64.MIFARE卡存储指纹数。
        /// 66.是否显示考勤状态。
        /// 67-68.暂无意义。
        /// 70.TCP端口。
        /// 71.UDP端口。
        /// 72.指纹算法版本。
        /// 73.人脸算法版本。
        /// 74.指静脉版本。
        /// 75.FaceFunOn。
        /// 76,PIN2Width。
        /// 77.IsSupportABCPin。
        /// 78.IMEFunOn。
        /// 79.isSupportAlarmExt。
        /// 80.~DCTZ。
        /// 81.~DOTZ。
        /// 8999.此时dwValue同时作为输入和输出参数，输入代表需获取的其他option名称,输出作为该option的值，此时类似GetSysOption。
        /// [注] 上述时间点的返回值均为一数值，换算为时间点的方法为：将该值转换为二进制，低8位表示分钟数，高8位表示小时数，如返回值为2860，则转换成二进制为101100101100，低8位为00101100，该值为44，高8位为00001011，该值为11，则实际时间点为11:44。
        /// </param>
        /// <returns>函数执行失败返回 -9999</returns>
        public static int GetDeviceInfo(int ID, int Info)
        {
            int RValue = 0;
            if (ZKGConf.GetZKClass(ID).GetDeviceInfo(ID, Info, ref RValue))
            {
                return RValue;
            }
            else
            {
                return -9999;
            }
        }

        /// <summary>
        /// 5.4.4
        /// 设置机器相关信息，例如语言、重复记录时间等 
        /// </summary>
        /// <param name="Info">欲设置的信息类型，范围为1—20，80，81。其含义参考GetDeviceInfo函数该参数含义</param>
        /// <param name="Value">欲设置的由dwInfo描述的信息的值</param>
        /// <returns></returns>
        public static bool SetDeviceInfo(int ID, int Info, int Value)
        {
            return ZKGConf.GetZKClass(ID).SetDeviceInfo(ID, Info, Value);
        }

        /// <summary>
        /// 5.4.5
        /// 把机器时间设置为和本地电脑时间一样，如需要设置指定时间，可参考SetDeviceTime2
        /// </summary>
        /// <returns></returns>
        public static bool SetDeviceTime(int ID)
        {
            return ZKGConf.GetZKClass(ID).SetDeviceTime(ID);
        }

        /// <summary>
        /// 5.4.6
        /// 设置机器时间（可指定时间）
        /// </summary>
        /// <param name="dateTime">要设置的时间</param>
        /// <returns></returns>
        public static bool SetDeviceTime(int ID, DateTime dateTime)
        {
            return ZKGConf.GetZKClass(ID).SetDeviceTime2(ID, dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second);
        }

        /// <summary>
        /// 5.4.7
        /// 获取设备时间
        /// </summary>
        /// <returns></returns>
        public static DateTime GetDeviceTime(int ID)
        {
            DateTime dt;
            int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;

            if (ZKGConf.GetZKClass(ID).GetDeviceTime(ID, ref year, ref month, ref day, ref hour, ref minute, ref second))
            {
                dt = new DateTime(year, month, day, hour, minute, second);
                return dt;
            }
            return DateTime.MinValue;
        }

        /// <summary>
        /// 5.4.8
        /// 获取机器序列号
        /// </summary>
        /// <returns></returns>
        public static string GetSerialNumber(int ID)
        {
            if (ZKGConf.GetZKClass(ID).GetSerialNumber(ID, out string dwSerialNumber))
            {
                return dwSerialNumber;
            }
            else
            {
                return "-9999";
            }
        }

        /// <summary>
        /// 5.4.9 
        /// 获取机器名称
        /// </summary>
        /// <returns></returns>
        public static string GetProductCode(int ID)
        {
            if (ZKGConf.GetZKClass(ID).GetProductCode(ID, out string ProductCode))
            {
                return ProductCode;
            }
            else
            {
                return "-9999";
            }
        }

        /// <summary>
        /// 5.4.11
        /// 获取SDK版本号
        /// </summary>
        /// <returns></returns>
        public static string GetSDKVersion(int ID)
        {
            string strVersion = "";
            if (ZKGConf.GetZKClass(ID).GetSDKVersion(ref strVersion))
            {
                return strVersion;
            }
            else
            {
                return "-9999";
            }
        }

        /// <summary>
        /// 5.4.12
        /// 获取机器IP地址
        /// </summary>
        /// <returns></returns>
        public static string GetDeviceIP(int ID)
        {
            string ipstr = "";
            if (ZKGConf.GetZKClass(ID).GetDeviceIP(ID, ref ipstr))
            {
                return ipstr;
            }
            else
            {
                return "0.0.0.0";
            }
        }

        /// <summary>
        /// 5.4.13
        /// 设置机器IP地址
        /// </summary>
        /// <param name="IPAddr">IP地址</param>
        /// <returns></returns>
        public static bool SetDeviceIP(int ID, string IPAddr)
        {
            return ZKGConf.GetZKClass(ID).SetDeviceIP(ID, IPAddr);
        }
        #endregion

        #region 5.5.1机器控制-------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 5.5.1.2
        /// 启用或者禁用机器，禁用即意味着关闭指纹头，键盘，卡模块等
        /// </summary>
        /// <param name="Flag">启用标志，1为启用，0为禁用</param>
        /// <returns></returns>
        public static bool EnableDevice(int ID, bool Flag)
        {
            return ZKGConf.GetZKClass(ID).EnableDevice(ID, Flag);
        }
        #endregion

        #region 5.5.2连机登记相关操作------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 5.5.2.2
        /// 登记用户，让机器进入登记用户状态，等待用户按指纹
        /// 1.使用该函数后，用户按三次指纹完成登记后，可能会出现按指纹不反应的情况，此时可用StartIdentify使机器进入等待状态。
        /// 2.Flag为0表示指纹模板无效，1表示指纹模板有效，3表示为胁迫指纹。 
        /// 3.人脸，FingerID固定传111，Flag固定传1
        /// </summary>
        /// <param name="EnrollID">需要登记的用户ID</param>
        /// <param name="FingerID">需要登记的用户的指纹索引号,范围为0－9 </param>
        /// <returns></returns>
        public static bool StartEnrollEx(int ID, string EnrollID, int FingerID, int Flag)
        {
            return ZKGConf.GetZKClass(ID).StartEnrollEx(EnrollID, FingerID, Flag);
        }

        /// <summary>
        /// 5.5.2.3
        /// 开始1：1比对
        /// </summary>
        /// <param name="EnrollID">需要验证的用户ID</param>
        /// <param name="FingerID">需要验证的用户的指纹索引号,范围为0－9</param>
        /// <returns></returns>
        public static bool StartVerify(int ID, string EnrollID, int FingerID)
        {
            return ZKGConf.GetZKClass(ID).StartVerify(Convert.ToInt32(EnrollID), FingerID);
        }

        /// <summary>
        /// 5.5.2.4
        /// 开始1：N 比对，使机器进入1：N验证状态
        /// </summary>
        /// <returns></returns>
        public static bool StartIdentify(int ID)
        {
            return ZKGConf.GetZKClass(ID).StartIdentify();
        }

        /// <summary>
        /// 5.5.2.5
        /// 取消机器当前的指纹登记状态
        /// </summary>
        /// <returns></returns>
        public static bool CancelOperation(int ID)
        {
            return ZKGConf.GetZKClass(ID).CancelOperation();
        }
        #endregion

        #region 5.5.4 其他----------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 5.5.4.1
        /// 获取指定考勤机API类发生的错误代码
        /// </summary>
        /// <returns></returns>
        public static int GetLastError(int ID)
        {
            int err = 0;
            ZKGConf.GetZKClass(ID).GetLastError(ref err);
            return err;
        }

        /// <summary>
        /// 5.5.4.5
        /// 准备以批处理模式上传数据，如在上传用户模板、用户信息等数据前使用该函数，
        /// 则在上传时SDK将临时地把这些数据都存储在缓冲区，然后在执行BatchUpdate将临时数据一起传进机器
        /// </summary>
        /// <param name="UpdateFlag">
        /// 存在指纹覆盖标志
        /// UpdateFlag1参数为存在指纹覆盖标志，即上传用户指纹模板时，如该用户该指纹索引已经存在指纹，
        /// 是否覆盖之前的质问模板，当该参数为1时，为强制覆盖，为0时，不覆盖。
        /// </param>
        /// <returns></returns>
        public static bool BeginBatchUpdata(int ID, int UpdateFlag)
        {
            return ZKGConf.GetZKClass(ID).BeginBatchUpdate(ID, UpdateFlag);
        }

        /// <summary>
        /// 5.5.4.6
        /// 开始批量上传数据，一般在使用函数BeginBatchUpdate后再上传完相关数据才使用该函数
        /// </summary>
        /// <returns></returns>
        public static bool BatchUpdata(int ID)
        {
            return ZKGConf.GetZKClass(ID).BatchUpdate(ID);
        }

        /// <summary>
        /// 5.5.4.7 
        /// 取消批处理模式上传数据，一般在使用BeginBatchUpdate后，
        /// 使用BatchUpdate之前可使用该函数，该函数释放为批处理上传准备的缓冲区
        /// </summary>
        /// <returns></returns>
        public static bool CancelBatchUpdate(int ID)
        {
            return ZKGConf.GetZKClass(ID).CancelBatchUpdate(ID);
        }

        /// <summary>
        /// 0.0.0.4
        /// </summary>
        /// <returns></returns>
        public static int GetBatchDataMode(int ID)
        {
            return ZKGConf.GetZKClass(ID).BatchDataMode;
        }
        public static void SetBatchDataMode(int ID, int Mode)
        {
            ZKGConf.GetZKClass(ID).BatchDataMode = Mode;
        }
        /// <summary>
        /// 5.5.4.17
        /// 获取socket连接状态，目前仅对TCP有效
        /// Tcp连接状态，0成功，-10004~-11000为SOCKET异常，软件无需再重试，可直接重连设备
        /// -9999 表示API执行不成功
        /// </summary>
        /// <returns></returns>
        public static int GetConnectStatus(int ID)
        {
            int dwErrorCode = 0;
            if (ZKGConf.GetZKClass(ID).GetConnectStatus(ref dwErrorCode))
            {
                return dwErrorCode;
            }
            else
            {
                return -9999;
            }
        }
        #endregion
    }
}
